<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>栈的创建和使用</title>
    <style>
      html {
        background: pink;
      }
      .circleBox {
        display: flex;
      }
      .circle {
        margin: 10px;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        cursor: pointer;
      }
      .red {
        background: red;
      }
      .green {
        background: green;
      }
      .blue {
        background: blue;
      }
      .undoList,
      .rollbackList {
        display: flex;
        flex-flow: column-reverse;
        margin-right: 20px;
        width: 70px;
        height: 450px;
        border: 1px solid black;
      }
      .listBox {
        display: flex;
      }
    </style>
  </head>
  <body>
    <h2>栈的创建和使用</h2>
    <div id="app">
      <main>
        <div>
          点击添加：
          <div class="circleBox">
            <div class="red circle" @click="onClickCircle('red')"></div>
            <div class="green circle" @click="onClickCircle('green')"></div>
            <div class="blue circle" @click="onClickCircle('blue')"></div>
          </div>
        </div>

        <div>
          <button @click="onUndo">撤销</button>
          <button @click="onBack">回退</button>
        </div>
        <div>
          <div>
            <p>当前的视图</p>
            <div :class="currentView" class="circle"></div>
          </div>
          <div class="listBox">
            <div>
              <p>可撤銷列表</p>
              <div class="undoList">
                <div
                  v-for="type in undoList"
                  :class="type"
                  class="circle"
                ></div>
              </div>
            </div>

            <div>
              <p>可回退列表</p>
              <div class="rollbackList">
                <div
                  v-for="type in rollbackList"
                  :class="type"
                  class="circle"
                ></div>
              </div>
            </div>
          </div>
        </div>
      </main>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      window.onload = function() {
        var record = createRecord();
        var app = new Vue({
          el: "#app",
          data: {
            currentView: "",
            undoList: [],
            rollbackList: []
          },
          methods: {
            onClickCircle(type) {
              record.addRecord(type);
              this.updateData();
            },
            onUndo() {
              record.undoRecord();
              this.updateData();
            },
            onBack() {
              record.rollbackRecord();
              this.updateData();
            },
            updateData() {
              this.currentView = record.getTopValue();
              this.undoList = record.getUndoStack();
              this.rollbackList = record.getrollbackStack();
            }
          }
        });
      };

      // 记录
      function createRecord() {
        let undoStack = createStrack();
        let rollbackStack = createStrack();
        const MAX_LIMIT = 6;
        return {
          getTopValue() {
            return undoStack.peek();
          },
          addRecord(data) {
            if (undoStack.size() >= MAX_LIMIT) {
              undoStack.shift();
            }
            undoStack.push(data);
            rollbackStack.clear();
          },
          undoRecord() {
            if (undoStack.empty()) return;
            const data = undoStack.pop();
            rollbackStack.push(data);
          },
          rollbackRecord() {
            if (rollbackStack.empty()) return;
            const data = rollbackStack.pop();
            undoStack.push(data);
          },
          getUndoStack() {
            return undoStack.getList();
          },
          getrollbackStack() {
            return rollbackStack.getList();
          }
        };
      }
      // 栈类
      function createStrack() {
        var list = [];
        return {
          /**
           * 入栈
           * @param {*} data
           */
          push(data) {
            list.push(data);
          },

          /**
           * 出栈
           */
          pop() {
            return list.pop();
          },
          size() {
            return list.length;
          },
          isEmpty() {
            return list.length === 0;
          },
          clear() {
            list = [];
          },
          // 用来做栈的最大长度限制操作
          shift() {
            list.shift();
          },
          peek() {
            return list[list.length - 1];
          },
          getList() {
            return list;
          }
        };
      }
    </script>
  </body>
</html>
